package com.gsafety.wellsfort.service.course;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.enums.QuestionTypeEnum;
import com.gsafety.wellsfort.common.util.ApiResponse;
import com.gsafety.wellsfort.common.util.ResultCode;
import com.gsafety.wellsfort.dao.anyineng.AnYiNengConfDAO;
import com.gsafety.wellsfort.dao.anyineng.AnYiNengDAO;
import com.gsafety.wellsfort.dao.anyineng.AnyinengOpreateLogDAO;
import com.gsafety.wellsfort.dao.course.*;
import com.gsafety.wellsfort.dao.knowledge.AnswerOptionDAO;
import com.gsafety.wellsfort.dao.knowledge.ExamPaperDAO;
import com.gsafety.wellsfort.dao.knowledge.ExamQuestionDAO;
import com.gsafety.wellsfort.dao.knowledge.QuestionDAO;
import com.gsafety.wellsfort.dao.security.AdminDAO;
import com.gsafety.wellsfort.domain.dto.course.AnswerChoiceItemDTO;
import com.gsafety.wellsfort.domain.dto.course.ExamAnswerSheetDTO;
import com.gsafety.wellsfort.domain.dto.course.MyExamDTO;
import com.gsafety.wellsfort.domain.dto.course.WorkAnswerSheetDTO;
import com.gsafety.wellsfort.domain.model.anyineng.AnYiNeng;
import com.gsafety.wellsfort.domain.model.anyineng.AnYiNengConf;
import com.gsafety.wellsfort.domain.model.anyineng.AnyinengOpreateLog;
import com.gsafety.wellsfort.domain.model.course.ExamAnswerRecord;
import com.gsafety.wellsfort.domain.model.course.ExamPublishRange;
import com.gsafety.wellsfort.domain.model.course.StudentExam;
import com.gsafety.wellsfort.domain.model.knowledge.*;
import com.gsafety.wellsfort.domain.model.organization.Student;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MyExamService {
    @Autowired(required = false)
    ExamPaperDAO examPaperDAO;
    @Autowired(required = false)
    AdminDAO adminDAO;
    @Autowired(required = false)
    StudentExamDAO studentExamDAO;
    @Autowired(required = false)
    LessonPeriodDAO lessonPeriodDAO;
    @Autowired(required = false)
    CourseDAO courseDAO;
    @Autowired(required = false)
    AnswerOptionDAO answerOptionDAO;
    @Autowired(required = false)
    ExamAnswerRecordDAO examAnswerRecordDAO;
    @Autowired(required = false)
    QuestionDAO questionDAO;
    @Autowired(required = false)
    ExamPublishRangeDAO examPublishRangeDAO;
    @Autowired(required = false)
    ExamQuestionDAO examQuestionDAO;
    @Autowired(required = false)
    AnYiNengConfDAO anYiNengConfDAO;
    @Autowired(required = false)
    AnYiNengDAO anYiNengDAO;
    @Autowired(required = false)
    AnyinengOpreateLogDAO anyinengOpreateLogDAO;

    public ApiResponse<List<MyExamListVO>> myExamList(MyExamDTO dtoParams) {
        ApiResponse<List<MyExamListVO>> apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        if (LoginContextUtil.getStudent() != null) {
            dtoParams.setStudentId(LoginContextUtil.getStudent().getId());
        }
        List<MyExamListVO> voList = examPaperDAO.myExamList(dtoParams);
        for (MyExamListVO myExamListVO : voList) {
            if (myExamListVO.getCreator() != null) {
                Admin admin = adminDAO.selectByPrimaryKey(myExamListVO.getCreator());
                if (admin != null) {
                    myExamListVO.setCreatorName(admin.getName());
                } else {
                    myExamListVO.setCreatorName("");
                }
            }
        }
        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(voList);
        apiResponse = ApiResponse.success(voList, (int) pageInfo.getTotal());
        return apiResponse;
    }

    public ApiResponse<List<MyQuestionVO>> myExamQuestionList(MyExamDTO dtoParams) {
        ApiResponse<List<MyQuestionVO>> apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        List<MyQuestionVO> voList = studentExamDAO.myExamQuestion(dtoParams);

        StudentExam stuExam = studentExamDAO.examDetail(dtoParams);
        AnswerAnalysisVO answerAnalysisVO;
        ExamAnswerRecord examAnswerRecord;
        List<AnswerOption> answerRightOptions;
        List<AnswerOption> myOptions;

        for (MyQuestionVO questionVo : voList) {
            List<AnswerOption> optionList = answerOptionDAO.selectByQuestionId(questionVo.getId());
            questionVo.setAnswerOptionList(optionList);

            //如果查看答案解析
            if (dtoParams.getIfViewAnalysis() != null && dtoParams.getIfViewAnalysis() == 1) {
                answerAnalysisVO = AnswerAnalysisVO.builder().build();
                examAnswerRecord = examAnswerRecordDAO.selectByStuExamIdAndQuestionId(stuExam.getId(), questionVo.getId());
                answerRightOptions = answerOptionDAO.selectRightByQuestionId(questionVo.getId());

                if (answerRightOptions.size() > 0) {
                    answerAnalysisVO.setRightAnswer(AnswerOptionUtils.parseOptionToString(answerRightOptions));
                    answerAnalysisVO.setRightAnswerIds(AnswerOptionUtils.parseOptionIdToString(answerRightOptions));
                }
                if (examAnswerRecord != null) {
                    String answerArrayStr = examAnswerRecord.getAnswerId() != null ? examAnswerRecord.getAnswerId() + "" : "" + "," + examAnswerRecord.getAnswerIds() != null ? examAnswerRecord.getAnswerIds() : "";
                    String[] optionIds = answerArrayStr.split(",");
                    myOptions = answerOptionDAO.selectByOptionIds(optionIds);
                    if (myOptions.size() > 0) {
                        answerAnalysisVO.setMyAnswer(AnswerOptionUtils.parseOptionToString(myOptions));
                        answerAnalysisVO.setMyAnswerIds(AnswerOptionUtils.parseOptionIdToString(myOptions));
                    }
                    if (answerAnalysisVO.getRightAnswerIds() != null) {
                        answerAnalysisVO.setIsRight(answerAnalysisVO.getRightAnswerIds().equals(answerAnalysisVO.getMyAnswerIds()) ? "正确" : "错误");
                    } else {
                        answerAnalysisVO.setIsRight("错误");
                    }
                } else {
                    answerAnalysisVO.setRightAnswer(AnswerOptionUtils.parseOptionToString(answerRightOptions));
                    answerAnalysisVO.setRightAnswerIds(AnswerOptionUtils.parseOptionIdToString(answerRightOptions));
                    answerAnalysisVO.setIsRight("未答");
                }
                answerAnalysisVO.setAnalyzing(questionVo.getAnalyzing());
                questionVo.setAnalyzing("");
                questionVo.setAnswerAnalysisVO(answerAnalysisVO);
            }
        }
        //答题开始时间
        stuExam.setStartTime(new Date());
        studentExamDAO.updateByPrimaryKeySelective(stuExam);
        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(voList);
        apiResponse = ApiResponse.success(voList, (int) pageInfo.getTotal());
        return apiResponse;
    }

    public ApiResponse<MyExamDetailVO> myExamDetail(MyExamDTO dtoParams) {
        ApiResponse<MyExamDetailVO> apiResponse = null;
        try {
            if (LoginContextUtil.getStudent() != null) {
                dtoParams.setStudentId(LoginContextUtil.getStudent().getId());
            } else {
                return ApiResponse.error(ResultCode.ERROR, "学生未登录");
            }
            StudentExam studentExam = studentExamDAO.examDetail(dtoParams);
            if (studentExam == null) {
                return ApiResponse.success();
            }
            MyExamDetailVO myWorkDetailVo = new MyExamDetailVO();
            BeanUtils.copyProperties(studentExam, myWorkDetailVo);
            if (studentExam.getExamId() != null) {
                myWorkDetailVo.setExamPaper(examPaperDAO.selectByPrimaryKey(studentExam.getExamId()));
            }
            if (studentExam.getLessonPeriodId() != null) {
                myWorkDetailVo.setLessonPeriod(lessonPeriodDAO.selectByPrimaryKey(studentExam.getLessonPeriodId()));
            }
            if (studentExam.getCourseId() != null) {
                myWorkDetailVo.setCourse(courseDAO.selectByPrimaryKey(studentExam.getLessonPeriodId()));
            }
            apiResponse = ApiResponse.success(myWorkDetailVo);
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            log.info("exception={}", e);
        }
        return apiResponse;
    }

    public ApiResponse<Set<IndexExamVO>> selectExamByParam(IndexQueryVO indexQueryVO) {
        List<IndexExamVO> list = studentExamDAO.selectExamByParam(indexQueryVO);
        Student student = LoginContextUtil.getStudent();
        if (student == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        TreeSet<IndexExamVO> set = new TreeSet<>();
        if (list != null && list.size() > 0) {
            for (IndexExamVO exam : list) {
                //查看发布范围
                List<ExamPublishRange> examPublishRangeList = examPublishRangeDAO.selectByCondition(exam.getExamPublishId(), student.getSchoolId(), student.getClassId());
                if (examPublishRangeList != null && examPublishRangeList.size() > 0) {
                    set.add(exam);
                }
            }
        }
        return ApiResponse.success(set);
    }

    public ApiResponse<ExamAnswerSheetDTO> submitExamQuAnswer(ExamAnswerSheetDTO examAnswerSheetDTO) {
        ApiResponse<ExamAnswerSheetDTO> apiResponse = null;
        try {
            Integer studentId;
            if (LoginContextUtil.getStudent() != null) {
                studentId = LoginContextUtil.getStudent().getId();
            } else {
                return ApiResponse.error(ResultCode.ERROR, "学生未登录");
            }
            MyExamDTO dtoParams = new MyExamDTO();
            dtoParams.setStudentId(studentId);
            dtoParams.setExamId(examAnswerSheetDTO.getExamId());
            dtoParams.setExamPublishId(examAnswerSheetDTO.getExamPublishId());
            StudentExam studentExam = studentExamDAO.examDetail(dtoParams);
            List<ExamAnswerRecord> list = examAnswerRecordDAO.selectByStuExamId(studentExam.getId());
            //如果答过一遍,提交答题卡清除原来的答题
            if (list.size() > 0) {
                examAnswerRecordDAO.deleteByStuExamId(studentExam.getId());
            }
            List<AnswerChoiceItemDTO> answerChoiceItemDTOS = examAnswerSheetDTO.getAnswerChoiceItemDTOList();
            ExamAnswerRecord answerRecord;
            Question question;
            AnswerOption answerOption;
            List<AnswerOption> rightAnswerOptionList;
            BigDecimal score = BigDecimal.ZERO;
            ExamPaper examPaper = examPaperDAO.selectByPrimaryKey(studentExam.getExamId());
            ExamQuestion examQuestion;
            for (AnswerChoiceItemDTO choiceItem : answerChoiceItemDTOS) {
                question = questionDAO.selectByPrimaryKey(choiceItem.getQuestionId());

                examQuestion = examQuestionDAO.selectByExamIdAndQuestionId(examPaper.getId(), choiceItem.getQuestionId());
                answerRecord = new ExamAnswerRecord();
                if (question.getExamType().intValue() == QuestionTypeEnum.SINGLE_ELECTION.value
                        || question.getExamType().intValue() == QuestionTypeEnum.JUDGE_QUESTION.value
                ) {
                    answerOption = answerOptionDAO.selectByPrimaryKey(choiceItem.getOptionId());
                    answerRecord.setAnswerId(choiceItem.getOptionId());
                    if (answerOption.getIsRight() == 1) {
                        score = score.add(examQuestion.getScore());
                    }
                } else if (question.getExamType().intValue() == QuestionTypeEnum.MULTIPLE_CHOICE.value) {
                    answerRecord.setAnswerIds(choiceItem.getOptionIds());
                    rightAnswerOptionList = answerOptionDAO.selectRightByQuestionId(choiceItem.getQuestionId());
                    if (rightAnswerOptionList.size() > 0) {
                        Set<String> rightSet = AnswerOptionUtils.parseOptionIdToHashSet(rightAnswerOptionList);
                        if (choiceItem.getOptionIds() != null) {
                            List<String> choiceArray = AnswerOptionUtils.stringToList(choiceItem.getOptionIds());
                            if (rightSet.containsAll(choiceArray) && choiceArray.size() == rightSet.size()) {
                                score = score.add(examQuestion.getScore());
                            }
                        }

                    }
                } else if (question.getExamType().intValue() == QuestionTypeEnum.SHORT_ANSWER.value) {
                    answerRecord.setAnswerContents(choiceItem.getAnswerContents());
                }
                answerRecord.setQuestionId(question.getId());
                answerRecord.setStudentExamId(studentExam.getId());
                answerRecord.setAnswerTime(new Date());
                examAnswerRecordDAO.insertSelective(answerRecord);
            }
            //答题完成后,修改考试信息
            studentExam.setFinishState((byte) 1);
            studentExam.setEndTime(new Date());
            studentExam.setScore(score);
            if (examPaper != null && examPaper.getPassingScore() != null) {
                if (examPaper.getPassingScore().doubleValue() <= score.doubleValue()) {
                    studentExam.setIsPassed((byte) 1);
                } else {
                    studentExam.setIsPassed((byte) 0);
                }
            }
            studentExamDAO.updateByPrimaryKeySelective(studentExam);

            //如果是安意能试卷,改一下安意能的状态;
            AnyinengOpreateLog opreateLog;
            AnYiNengConf anYiNengConf = anYiNengConfDAO.selectAnYiNengConf();
            AnYiNeng anYiNeng = anYiNengDAO.selectByStudentId(studentId);
            if (anYiNeng != null) {
                if (studentExam.getExamId() == anYiNengConf.getAnyinengExamId()) {
                    anYiNeng.setState((byte) 1);
                    //首次安意能分计算
                    double d1 = score.doubleValue() / examPaper.getCurrentTotalScore().doubleValue();
                    BigDecimal aynScore = BigDecimal.valueOf(500 * d1);
                    anYiNeng.setVal(aynScore);
                    anYiNengDAO.updateByPrimaryKeySelective(anYiNeng);
                    opreateLog = AnyinengOpreateLog.builder().anyinengId(anYiNeng.getId())
                            .datetime(new Date())
                            .operateType(3)
                            .remark("安意能首次测评得分")
                            .val(aynScore).build();
                    anyinengOpreateLogDAO.insertSelective(opreateLog);
                }
                if(studentExam.getIsCountAyn()==null||studentExam.getIsCountAyn()==0){
                    Integer finishNum = studentExamDAO.countFinishByState(studentId, 1,anYiNeng.getCreateTime());
                    double C1 = 0, C2 = 0;
                    if (finishNum >= anYiNengConf.getExamAddMax().intValue()) {
                        C1 = 0;
                    } else {
                        C1 = anYiNengConf.getExamAddUp().intValue();
                    }
                    if (examPaper.getCurrentTotalScore() != null && examPaper.getCurrentTotalScore().intValue() != 0) {
                        C2 = score.doubleValue() / examPaper.getCurrentTotalScore().doubleValue();
                    }
                    double C = C1 + anYiNengConf.getExamResultScore().doubleValue() * C2;
                    BigDecimal aynVal = anYiNeng.getVal().add(BigDecimal.valueOf(C));
                    if (aynVal.intValue() > 1000) {
                        aynVal = BigDecimal.valueOf(1000);
                    }
                    //修改安意分值
                    anYiNeng.setVal(aynVal);
                    anYiNeng.setUpdateTime(new Date());
                    anYiNeng.setModified(studentId);
                    anYiNengDAO.updateByPrimaryKeySelective(anYiNeng);
                    //记录安意能操作日志
                    opreateLog = AnyinengOpreateLog.builder().anyinengId(anYiNeng.getId())
                            .datetime(new Date())
                            .operateType(3)
                            .remark("考试评估")
                            .val(BigDecimal.valueOf(C)).build();
                    anyinengOpreateLogDAO.insertSelective(opreateLog);

                    studentExam.setIsCountAyn((byte)1);
                    studentExamDAO.updateByPrimaryKeySelective(studentExam);
                }
            }

            apiResponse = ApiResponse.success(examAnswerSheetDTO);
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }
}
